#include "glwidget.h"
#include <cg/cg.h>
#include <cg/cgGL.h>


//static variables 
static CGcontext myCgContext;
static CGprofile myCgVertexProfile , myCgFragmentProfile;
static CGprogram myCgVertexProgram , myCgFragmentProgram;
static const char * myProgramName = "01_vertex_program", *myVertexProgramFileName = "C2E1v_green.cg", *myVertexPogramName = "C2E1v_green";
static const char * myFragmentProgramFileName  = "C2E1f_yellow.cg",*myFragmentProgramName = "C2E1f_yellow";



//check for cg errors 

static void checkForCgError(const char * situation)
{
	CGerror  error;
	const char *str = cgGetLastErrorString(&error);
	if(error != CG_NO_ERROR){
		QString info = QString("%1 %2 %3").arg(myProgramName).arg(situation).arg(str);
		QMessageBox::information(NULL,"cg error",info);
		exit(1);
	}
}



GLWidget::GLWidget(QWidget *parent)
	: QGLWidget(parent)
{
	resize(500,500);
}

GLWidget::~GLWidget()
{
	cgDestroyProgram(myCgVertexProgram);
	cgDestroyProgram(myCgFragmentProgram);
	cgDestroyContext(myCgContext);
}

void GLWidget::initializeGL()
{
	glClearColor(1.0,0.5,1.0,1.0);
	initCG();
}

void GLWidget::resizeGL(int w , int h)
{
	if(h==0)
		h=1;
	glViewport(0,0,w,h);
}


void GLWidget::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT);
	//bind vertex program 
	cgGLBindProgram(myCgVertexProgram);
	checkForCgError("binding vertex program");
	//enable vertex profile 
	cgGLEnableProfile(myCgVertexProfile);
	checkForCgError("enabling vertex profile");
	//
	//bind fragment program 
	cgGLBindProgram(myCgFragmentProgram);
	checkForCgError("binding fragment program");
	//enable fragment profile 
	cgGLEnableProfile(myCgFragmentProfile);
	checkForCgError("enabling fragment profile");
	//draw model and prepare vertex data 
	
	//transform 
//	glTranslatef(1.0,0.0,0.0);

	drawTriangle();
	//disable vertex profile 
	cgGLDisableProfile(myCgVertexProfile);
	checkForCgError("disabling vertex profile");
	//disable fragment profile
	cgGLDisableProfile(myCgFragmentProfile);
	checkForCgError("disabling fragment profile");
	glFlush();
}

void GLWidget::drawTriangle()
{
	//glColor3f(0.0,1.0,0.0);
	glBegin(GL_TRIANGLES);
		glVertex2f(-1.0,1.0);
		glVertex2f(1.0,1.0);
		glVertex2f(0.0,-1.0);
	glEnd();
}



void GLWidget::initCG()
{
	//creating context of cg 
	myCgContext = cgCreateContext();
	checkForCgError("creating context");
	//set debug mode 
	cgGLSetDebugMode(CG_FALSE);
	cgSetParameterSettingMode(myCgContext,CG_DEFERRED_PARAMETER_SETTING);

	//get cg vertex profile 
	myCgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
	cgGLSetOptimalOptions(myCgVertexProfile);
	checkForCgError("selecting vertex profile");

	//get cg fragment profile 
	myCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
	cgGLSetOptimalOptions(myCgFragmentProfile);
	checkForCgError("selecting fragment profile");

	//creating vertex program 
	myCgVertexProgram  = cgCreateProgramFromFile(myCgContext,CG_SOURCE,myVertexProgramFileName,myCgVertexProfile,myVertexPogramName,NULL);
	checkForCgError("creating vertex program from file");
	//load vertex program 
	cgGLLoadProgram(myCgVertexProgram);
	checkForCgError("loading vertex program");


	//creating fragment program 
	myCgFragmentProgram = cgCreateProgramFromFile(myCgContext,CG_SOURCE,myFragmentProgramFileName,myCgFragmentProfile,myFragmentProgramName,NULL);
	checkForCgError("creating fragment program");
	//load fragment program 
	cgGLLoadProgram(myCgFragmentProgram);


}